#!/usr/bin/env python
from PyQt4 import QtGui
from PyQt4.QtGui import QWidget ,QPushButton,QVBoxLayout,QTabWidget

from PyQt4 import QtCore
from PyQt4.QtCore import Qt,SIGNAL

import os, socket
from lib.uicompile import loadUiType
from lib.profile_manager import ProfileManager

ui_path= os.path.join ( os.getcwd() , 'ui','main.ui')
UI_Object, Qt_Type = loadUiType(ui_path)

from lib.communication import WoxxyListener, WoxxySend, WoxxyBroadcastListener, WoxxyBroadcast, WoxxyServer
from gui.widget import ProfileWidget, TransfertWidget, WoxxyMessage

from set_options import SetOptions
from add_contact import AddContact
from chat import WoxxyChat

from lib.const import *

class MainWindow ( Qt_Type, UI_Object ):
	def __init__ ( self, parent = None ):
		super ( Qt_Type, self ).__init__ ( parent )
		self.__index = 0
		self.setupUi ( self )

		self.ok_toclose = False

		self.__create_systemtray ()

		self.profilemanager = ProfileManager ()

		self.__set_profiles ()

		self.woxxy_listener = WoxxyServerThread ( self )
		self.woxxy_listener.start()

		self.woxxy_broadcast_listener = WoxxyBroadcastServerThread ( self )
		self.woxxy_broadcast_listener.start()

		self.woxxy_socket_listener = WoxxySocketServerThread ( self )
		self.woxxy_socket_listener.start()

		self.options = SetOptions()

		self.chat = WoxxyChat()
		self.tx_req = WoxxyMessage ( "aaaa", 100, 1 )

		self.connect ( self.action_exit, SIGNAL ( 'triggered()' ), self.__app_exit )
		self.connect ( self.set_options, SIGNAL ( 'triggered()' ), self.__show_options )
		self.connect ( self.btn_addcontact, SIGNAL ( 'clicked()' ), self.__add_contact )


		self.connect ( self, SIGNAL ( "add_me" ), self.__add_me )
		self.connect ( self, SIGNAL ( "add_transfer" ) , self.__add_transfert_file )
		self.connect ( self, SIGNAL ( "remove_transfer" ) , self.__remove_transfert_file )
		self.connect ( self, SIGNAL ( "file_received" ) , self.__file_received )
		self.connect ( self, SIGNAL ( "open_chat" ) , self.__openchat )
		#self.connect ( self, SIGNAL ( "ask_for_file" ) , self.__ask_for_file )


		#State machine
		self.state_machine  = QtCore.QStateMachine ( self )
		self.state_hide = QtCore.QState ( self.state_machine )
		self.state_show = QtCore.QState ( self.state_machine )
		self.state_machine.setInitialState ( self.state_hide )

		self.state_hide.assignProperty ( self.file_transf, "maximumWidth", 0 )
		self.state_show.assignProperty ( self.file_transf, "maximumWidth", 500 )


		t_hide =  self.state_hide.addTransition ( self.btn_show_trans.clicked, self.state_show )
		t_hide.addAnimation ( QtCore.QPropertyAnimation ( self.file_transf, 'maximumWidth', self.state_show ) )

		t_show =  self.state_show.addTransition ( self.btn_show_trans.clicked, self.state_hide )
		t_show.addAnimation ( QtCore.QPropertyAnimation ( self.file_transf, 'maximumWidth', self.state_hide ) )

		self.state_machine.start()

		WoxxyBroadcast ( "add_me:1" )

	def __openchat ( self ):
		self.chat.show()

	def pippo ( self, fname, size, secure ):
		res = self.tx_req.exec_ ()
	
		print res

		return False

	def __set_profiles ( self ):
		profiles = self.profilemanager.get_profiles ()
		for profile in profiles:
			self.__insert_profile ( profile )


	def __insert_profile ( self, profile ):
		#profilewidget = ProfileWidget ( profile, self.scrollAreaWidgets )
		profilewidget = ProfileWidget ( profile, self )
		self.verticalLayout_2.insertWidget ( 0,  profilewidget )


	def __create_systemtray ( self ):
		self.trayicon = QtGui.QSystemTrayIcon( self.windowIcon (), self)

		self.trayicon.setContextMenu(self.menuFile )
		self.trayicon.show()

		self.connect ( self.trayicon, QtCore.SIGNAL ( "activated(QSystemTrayIcon::ActivationReason)" ), self.__tray_activated )

	def __tray_activated ( self, reason ):
		if reason == QtGui.QSystemTrayIcon.DoubleClick:
			self.show ()

	def __file_received ( self, fname ):
		self.trayicon.showMessage ( "File ricevuto", "Hai ricevuto il file: " + fname )

	def __app_exit ( self ):
		self.ok_toclose = True
		self.woxxy_listener.quit ()
		self.woxxy_broadcast_listener.quit ()
		self.close()


	def __show_options ( self ):
		self.options.show()

	def __add_contact ( self ):
		self.trayicon.showMessage ( "ciaooo" ,"sono un messaggio")
		return

		dlg_addcontact = AddContact ()
		if dlg_addcontact.exec_():
			ipaddr = str ( dlg_addcontact.ip.text() )
			self.add_contact_from_ip ( ipaddr, True )

	def __add_me ( self, ipaddr, add_me = False ):
		self.add_contact_from_ip ( ipaddr, add_me = add_me )

	def add_contact_from_ip ( self, ipaddr, add_me = False ):
		print "Contact from IP: %s - add_me: %s" % ( ipaddr, add_me )

		ws = WoxxySend ()
		try:
			res = ws.identify ( ipaddr )
		except:
			pass

		newprofile = self.profilemanager.add_profile ( ipaddr, res [ 'name' ] )
		if newprofile:
			self.__insert_profile ( newprofile )
			#add_me = True

		if add_me:
			WoxxyBroadcast ( "add_me:2" )

	def __add_transfert_file ( self, file_name, sender ):
		transf_widget = TransfertWidget ( self, file_name, sender )
		self.file_transfert_layout.insertWidget ( 0, transf_widget )

	def __remove_transfert_file ( self, who ):
		print who

	# =================================================================================
	# EVENTS
	# =================================================================================
	def closeEvent  ( self, event ):
		if self.ok_toclose:
			self.trayicon.hide()
			event.accept()
		else:
			event.ignore()
			self.hide()


class WoxxyServerThread ( QtCore.QThread ):
	def __init__ ( self, woxxy_instance = None, parent = None ):
		#super ( WoxxyServerThread, self ).__init__ ( parent )
		QtCore.QThread.__init__(self, parent)

		self.exit = False
		self.woxxy_instance = woxxy_instance
		self.wl = WoxxyListener ( woxxy_instance )
		print "Thread Ready"

	def __del__ ( self ):
		self.exit = True
		if self.wl: self.wl.quit ()
		self.wait ()

	"""
	def run ( self ):
		print "RUN"

		self.wl.srv.server_sock.listen ( 10 )

		while not self.exit:
			self.wl.srv.serveOnce ()

		print "END"
	"""

	def run ( self ):
		print "RUN"
		while not self.exit:
			self.wl.srv.handle_request ()

		print "END"

		self.wl.srv._main_sock.close ()

		print "QUIT"


	def quit ( self ):
		print "QUIT"
		self.wl.quit ()


class WoxxyBroadcastServerThread ( QtCore.QThread ):
	def __init__ ( self, woxxy_instance = None, parent = None ):
		#super ( WoxxyServerThread, self ).__init__ ( parent )
		QtCore.QThread.__init__(self, parent)

		self.exit = False
		self.woxxy_instance = woxxy_instance
		self.wbl = WoxxyBroadcastListener ( woxxy_instance )
		self.wbl.start ()
		print "Broadcast Listener Thread Ready"

	def __del__ ( self ):
		self.exit = True
		if self.wbl: self.wbl.quit ()
		self.wait ()

	def run ( self ):
		while not self.exit:
			( addr, msg ) = self.wbl.handle_request ()
			if msg == 'add_me:2':
				add_me = False
			else:
				add_me = True

			self.woxxy_instance.emit ( SIGNAL ( "add_me" ), addr [ 0 ], add_me )


	def quit ( self ):
		print "Broadcast QUIT"
		self.wbl.quit ()

class WoxxySocketServerThread ( QtCore.QThread ):
	def __init__ ( self, woxxy_instance = None, parent = None ):
		QtCore.QThread.__init__(self, parent)

		self.woxxy_instance = woxxy_instance

		self.ip_addr = 0
		self.port = WOXXY_SOCKET
		self.exit = False
		self.full_fname = ""

		self.sock = None

		self.sock = socket.socket ( socket.AF_INET, socket.SOCK_STREAM, 0 )
		#self.sock.settimeout ( 3.0 )

		self.sock.bind ( ( '0.0.0.0', WOXXY_SOCKET ) )
		self.sock.listen ( 100 )

		print "Socket Server Ready"

	def __del__ ( self ):
		self.exit = True
		self.wait ()

	def run ( self ):
		print "SOCKET SERVER RUN"	

		full_fname = "/ramdisk/aaa.txt"

		while not self.exit:
			conn, addr = self.sock.accept ()
			print "--ACCEPT: %s %s" % ( conn, addr )

			ws = WoxxyServer ( self.woxxy_instance )
			ws.put_socket ( conn, addr )

	def quit ( self ):
		print "QUIT"
		if self.sock: 
			self.sock.shutdown ( socket.SHUT_RDWR )
			self.sock.close ()
